// Compiler for PHP (aka KPHP)
// Copyright (c) 2024 LLC «V Kontakte»
// Distributed under the GPL v3 License, see LICENSE.notice.txt
#pragma once

#include <cassert>

#ifdef __x86_64__
#ifdef __linux__
/*
 *
 * For X86_64 Linux platform we use own implementation of user context manipulation routines in the same manner as in libc.
 * But without signals state storing/restoring.
 * IMPORTANT! USER HAVE TO MANUALLY CONTROL SIGNALS STATE!
 *
 */
#include "common/ucontext/linux/x86_64/context.h"
using ucontext_t_portable = kcontext_t;

extern "C" {
int getcontext_portable(ucontext_t_portable*);
void makecontext_portable(ucontext_t_portable*, void (*)(), int, ...);
int setcontext_portable(const ucontext_t_portable*);
int swapcontext_portable(ucontext_t_portable*, const ucontext_t_portable*);
}

#elif __APPLE__
#include "common/ucontext/darwin/x86_64/context.h"
using ucontext_t_portable = ucontext_t;

#define getcontext_portable getcontext
#define makecontext_portable makecontext
#define setcontext_portable setcontext
#define swapcontext_portable swapcontext

#else
static_assert(false, "Unsupported OS for x86_64 platform");
#endif

#elif defined(__aarch64__) || defined(__arm64__)

#ifdef __linux__
#include "common/ucontext/linux/aarch64/context.h"
using ucontext_t_portable = ucontext_t;

#define getcontext_portable getcontext
#define makecontext_portable makecontext
#define setcontext_portable setcontext
#define swapcontext_portable swapcontext

#elif __APPLE__
// For M1, we can't use native makecontext() and others: they compile, but hang up when called
#include "common/ucontext/darwin/aarch64/context.h"
using ucontext_t_portable = libucontext_ucontext;

extern "C" {
void makecontext_portable(ucontext_t_portable*, void (*)(), int, ...);
int getcontext_portable(ucontext_t_portable*);
int setcontext_portable(const ucontext_t_portable*);
int swapcontext_portable(ucontext_t_portable*, const ucontext_t_portable*);
}
#else
static_assert(false, "Unsupported OS for aarch64 platform");
#endif

#endif
